package cn.myframe.db;

import cn.myframe.db.datascope.DataScopeInterceptor;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * 启用mybatis-plus和druid
 * 
 * @author  ynz
 * @email   ynz@myframe.cn
 * @version 创建时间：2017年11月21日 下午12:24:01
 */
@ConditionalOnBean(name="dataSource")
@Configuration
public class MybatisPlusConf {

	private static final Log log = LogFactory.getLog(MybatisPlusConf.class);

    /**
	 * mybatisPlus全局配置
	 */
	@Bean(name = "globalConfig")
	public GlobalConfiguration globalConfig(
			@Value("${mybatis-plus.global-config.id-type}") Integer idType, //主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
			@Value("${mybatis-plus.global-config.db-column-underline}") Boolean dbColumnUnderline //驼峰下划线转换
	) {
		log.debug("init GlobalConfiguration .......");
		GlobalConfiguration globalConfig = new GlobalConfiguration();
		// 主键类型
		globalConfig.setIdType(idType);
		// 驼峰下划线转换
		globalConfig.setDbColumnUnderline(dbColumnUnderline);
		globalConfig.setRefresh(true);
		globalConfig.setDbType("oracle");
		// 数据库大写下划线转换
		globalConfig.setCapitalMode(true);
		return globalConfig;
	}

	@Bean
	public SqlSessionFactory sqlSessionFactory(GlobalConfiguration globalConfig, @Qualifier("dataSource") DataSource dataSource,
											   @Value("${mybatis.mapperLocations}") String mapperLocations,
											   @Value("${mybatis.configLocation}") String configLocation,
											   DatabaseIdProvider databaseIdProvider) throws Exception {
		log.debug("init SqlSessionFactory");
		String typeAliasesPackage = "cn.myframe.shiro.entity";
		MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
		// 数据源
		sqlSessionFactory.setDataSource(dataSource);
		// 全局配置
		sqlSessionFactory.setGlobalConfig(globalConfig);
		sqlSessionFactory.setDatabaseIdProvider(databaseIdProvider);
		Interceptor[] interceptor = {new PaginationInterceptor(),new DataScopeInterceptor()};
		// 分页插件
		sqlSessionFactory.setPlugins(interceptor);
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		try {
			// 自动扫描Mapping.xml文件
			sqlSessionFactory.setMapperLocations(resolver.getResources(mapperLocations));
			sqlSessionFactory.setConfigLocation(resolver.getResource(configLocation));
			sqlSessionFactory.setTypeAliasesPackage(typeAliasesPackage);
			return sqlSessionFactory.getObject();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * MyBatis 动态扫描
	 * @return
	 */
	@Bean
	public MapperScannerConfigurer mapperScannerConfigurer() {
		log.debug("init basisMapperScannerConfigurer");
		MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
		String basePackage = "cn.myframe.shiro.dao,cn.myframe.dao";
		mapperScannerConfigurer.setBasePackage(basePackage);
		return mapperScannerConfigurer;
	}

	/**
	 * 配置事务管理
	 * @param dataSource
	 * @return
	 */
	@Bean
	public DataSourceTransactionManager transactionManager(@Qualifier(value = "dataSource")DruidDataSource dataSource) {
		log.debug("init basisTransactionManager");
		return new DataSourceTransactionManager(dataSource);
	}
	
	@Bean
	public DatabaseIdProvider databaseIdProvider() {
		//mapper中的_databaseId才会生效
		DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
		Properties p = new Properties();
		p.setProperty("Oracle", "Oracle");
		p.setProperty("MySQL", "MySQL");
		databaseIdProvider.setProperties(p);
		return databaseIdProvider;
	}
}
